package com.dream.web.controller.web;

import com.dream.common.constans.ErrorCode;
import com.dream.common.constans.RedisKeysDefine;
import com.dream.common.exception.RespErrorException;
import com.dream.common.utils.JsonUtils;
import com.dream.common.utils.ThreadContextUtil;
import com.dream.common.utils.ThreadPoolService;
import com.dream.dto.DataResponse;
import com.dream.dto.request.GroupMemberBatchRequest;
import com.dream.dto.request.ChangeGroupMemberRoleRequest;
import com.dream.dto.socket.SocketBean;
import com.dream.entity.GroupMember;
import com.dream.mapper.GroupMemberMapper;
import com.dream.service.ProcedureServiceImpl;
import com.dream.service.basic.BaseServiceHelper;
import com.dream.service.basic.RedisCacheService;
import com.dream.web.aop.annotation.CommonResponse;
import com.dream.net.socket.base.SocketController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;

@RestController
@RequestMapping("/api/webNote")
@Api(tags = "web版云笔记接口")
public class GroupManagerController {

    @Resource
    private SocketController socketController;
    @Resource
    private GroupMemberMapper groupMemberMapper;
    @Resource
    private RedisCacheService redisCacheService;
    @Resource
    private ProcedureServiceImpl procedureService;


    @CommonResponse
    @GetMapping(value = "/groupMembers")
    @ApiOperation(value = "纯粹获取群成员(Web版)", response = GroupMember.class)
    public Object groupMembers() {
        String userName = ThreadContextUtil.get("userName").toString();
        SocketBean socketBean = new SocketBean();
        socketBean.command = 5;
        ThreadPoolService.execute(() -> socketController.sendCommand(userName, socketBean));
        return groupMemberMapper.select(GroupMember.builder().userName(userName).build());
    }


    @CommonResponse
    @GetMapping(value = "/memberRoles")
    @ApiOperation(value = "获取群成员角色(Web版)", response = GroupMemberBatchRequest.class)
    public Object memberRoles() {
        String userName = ThreadContextUtil.get("userName").toString();
        return procedureService.getMemberRoles(userName);
    }


    @CommonResponse
    @GetMapping(value = "/memberRole/{friendId}")
    @ApiOperation(value = "获取単个群成员角色(Web版)", response = GroupMember.class)
    public Object memberRole(@PathVariable String friendId) {
        String userName = ThreadContextUtil.get("userName").toString();
        GroupMemberBatchRequest batchRequest = BaseServiceHelper.getProcedureServiceImpl().getMemberRoles(userName);
        GroupMember groupMember = new GroupMember();
        if (batchRequest.roleMap.get("touchPackList") != null && batchRequest.roleMap.get("touchPackList").contains(friendId)) {
            groupMember.isTouchPack = 1;
        } else {
            groupMember.isTouchPack = 2;
        }
        if (batchRequest.roleMap.get("managerList") != null && batchRequest.roleMap.get("managerList").contains(friendId)) {
            groupMember.isManager = 1;
        } else {
            groupMember.isManager = 2;
        }
        if (batchRequest.roleMap.get("blackList") != null && batchRequest.roleMap.get("blackList").contains(friendId)) {
            groupMember.isBlackList = 1;
        } else {
            groupMember.isBlackList = 2;
        }
        if (batchRequest.roleMap.get("insideUserList") != null && batchRequest.roleMap.get("insideUserList").contains(friendId)) {
            groupMember.isInsideUser = 1;
        } else {
            groupMember.isInsideUser = 2;
        }
        return groupMember;
    }


    @CommonResponse
    @PostMapping(value = "/changeGroupMemberRole")
    @ApiOperation(value = "更新群成员角色(単个)", response = DataResponse.class)
    public Object groupMembers(@RequestBody ChangeGroupMemberRoleRequest request) {
        String userName = ThreadContextUtil.get("userName").toString();
        //设置管理员或者黑名単需要通知app
        if (request.roleType == 1 || request.roleType == 3) {
            if (!SocketController.socketUserChannels.containsKey(userName)) {
                throw new RespErrorException("请打开app或者划掉app重新打开");
            }
        }
        //同时更新db外,管理员、黑名単、踢出还需要通知app外
        GroupMember groupMember = new GroupMember();
        //groupMember.groupId = request.groupId;
        groupMember.userName = userName;
        groupMember.friendId = request.friendId;
        groupMember = groupMemberMapper.selectOne(groupMember);
        if (groupMember == null) {
            throw new RespErrorException("未找到匹配好友记录");
        }
        int roleVal = 0;
        switch (request.roleType) {
            case 1:
                groupMember.isManager = request.isOpen;
                roleVal = 61;
                break;
            case 2:
                groupMember.isTouchPack = request.isOpen;
                break;
            case 3:
                groupMember.isBlackList = request.isOpen;
                roleVal = 62;
                break;
            case 4:
                groupMember.isInsideUser = request.isOpen;
                break;
            case 5:
                groupMemberMapper.delete(groupMember);
                roleVal = 7;
                break;
            default:
                break;
        }

        String memberStr = JsonUtils.toJSONString(groupMember);
        if (request.roleType == 1 || request.roleType == 2 || request.roleType == 3 || request.roleType == 4) {
            groupMemberMapper.replaceGroupMemberList(Collections.singletonList(groupMember));
            redisCacheService.hset(RedisKeysDefine.USER_ROLE, groupMember.friendId, memberStr);
            //删除成本有点大,但省去遍历更新缓存,db连接有缓存可忽略效率问题
            redisCacheService.del(RedisKeysDefine.USER_ROLES.concat(userName));
        }
        int finalRoleVal = roleVal;
        ThreadPoolService.execute(() -> {
            if (finalRoleVal > 0) {
                SocketBean socketBean = new SocketBean();
                socketBean.command = finalRoleVal;
                socketBean.data = memberStr;
                socketController.sendCommand(userName, socketBean);
            }
        });
        return 1;
    }


    @CommonResponse
    @PostMapping(value = "/changeGroupMembersRole")
    @ApiOperation(value = "更新群成员角色(多个)", response = DataResponse.class)
    @Deprecated
    public Object groupMembers(@RequestBody GroupMemberBatchRequest request) {
        String userName = ThreadContextUtil.get("userName").toString();
        if (CollectionUtils.isEmpty(request.roleMap)) {
            throw new RespErrorException(ErrorCode.params_error);
        }
        //其实不存在新增操作,因为设1置角色一定是存在这个成员的，如果不存在，那么以现有设置成员设置也没关系，不做insert
        Map<String, SocketBean> noticeList = new HashMap<>(20);
        Map<String, GroupMember> updateRecord = new HashMap<>(20);

        request.roleMap.forEach((k, v) -> v.forEach(e -> {
            //开辟堆内存过多隐患,不过操作量不大gc回收问题不大
            GroupMember each = updateRecord.getOrDefault(e, new GroupMember());
            each.groupId = request.groupId;
            each.userName = userName;
            each.friendId = e;

            if ("touchPackList".equals(k)) {
                each.isTouchPack = 1;
            }
            if ("managerList".equals(k)) {
                each.isManager = 1;

                SocketBean socketBean = noticeList.getOrDefault(e, new SocketBean());
                socketBean.command = 61;
                socketBean.data = JsonUtils.toJSONString(each);
                noticeList.put(e, socketBean);
            }
            if ("blackList".equals(k)) {
                each.isBlackList = 1;

                SocketBean socketBean = noticeList.getOrDefault(e, new SocketBean());
                socketBean.command = 62;
                socketBean.data = JsonUtils.toJSONString(each);
                noticeList.put(e, socketBean);
            }
            if ("insideUserList".equals(k)) {
                each.isInsideUser = 1;
            }
            updateRecord.put(e, each);
        }));

        //以用户维度推送
        ThreadPoolService.execute(() -> noticeList.values().forEach(e -> socketController.sendCommand(userName, e)));

        return groupMemberMapper.updateListByAssemblyCondition(new ArrayList<>(updateRecord.values()));
    }


}


